;(function () {
    var SchemeConstants = {
        openBluetoothAdapter: 'ble_open_adapter',
        closeBluetoothAdapter: 'ble_close_adapter',
        getBluetoothAdapterState: 'ble_get_adapter_state',
        onBluetoothAdapterStateChange: 'ble_on_adapter_state_change',
        startBluetoothDevicesDiscovery: 'ble_start_device_discovery',
        stopBluetoothDevicesDiscovery: 'ble_stop_device_discovery',
        getBluetoothDevices: 'ble_get_devices',
        onBluetoothDeviceFound: 'ble_on_device_found',
        getConnectedBluetoothDevices: 'ble_get_connected_devices',
        createBLEConnection: 'ble_create_connection',
        closeBLEConnection: 'ble_close_connection',
        getBLEDeviceServices: 'ble_get_device_services',
        getBLEDeviceCharacteristics: 'ble_get_device_characteristics',
        readBLECharacteristicValue: 'ble_read_characteristic_value',
        writeBLECharacteristicValue: 'ble_write_characteristic_value',
        notifyBLECharacteristicValueChange: 'ble_notify_characteristic_value_change',
        onBLEConnectionStateChange: 'ble_on_connection_state_change',
        onBLECharacteristicValueChange: 'ble_on_characteristic_value_change',
    };

    var _identifer = (new Date()).getTime();

    var _callCommonFunction = function (object, string) {
        object['identifier'] = _identifer;
        window.pajkDispatchScheme(function (res) {
            if (!object) {
                return;
            }

            if (typeof (object['success']) == 'function') {
                console.log(string, '----success');
                object['success'](res);
            }
            if (typeof (object['complete']) == 'function') {
                console.log(string, '----complete');
                object['complete'](res);
            }
        }, function (res) {
            if (!object) {
                return;
            }
            if (typeof (object['fail']) == 'function') {
                console.log(string, '-----fail');
                object['fail'](res);
            }
            if (typeof (object['complete']) == 'function') {
                console.log(string, '-----complete');
                object['complete'](res);
            }
        }, object, string);
    };


    /**
     * 十六进制字符串转ArrayBuffer
     */
    var _hex2ab = function (hex) {
        var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {//此处正则正式引入js时需要去除一个"\"
            return parseInt(h, 16);
        }));

        var buffer = typedArray.buffer;
        return buffer;
    };

    // ArrayBuffer转16进度字符串
    var _ab2hex = function (buffer) {
        var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
            return ('00' + bit.toString(16)).slice(-2);
        });
        return hexArr.join('');
    };

    var PAG_NATIVE = window.PAG_NATIVE || (window.PAG_NATIVE = {});

    /*
     * PAG_NATIVE.openBluetoothAdapter(Object object)
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.openBluetoothAdapter = function (object) {
        _callCommonFunction(object, SchemeConstants.openBluetoothAdapter);
    };

    /*
     * PAG_NATIVE.closeBluetoothAdapter(Object object)
     * 关闭蓝牙连接，释放资源
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.closeBluetoothAdapter = function (object) {
        _callCommonFunction(object, SchemeConstants.closeBluetoothAdapter);
    };

    /*
     * PAG_NATIVE.getBluetoothAdapterState(Object object)
     * 获取蓝牙适配器状态，如果蓝牙未开或不可用，这里可用检测到
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.getBluetoothAdapterState = function (object) {
        console.log("PAG_NATIVE.getBluetoothAdapterState");
        _callCommonFunction(object, SchemeConstants.getBluetoothAdapterState);
    };

    /*
     * PAG_NATIVE.onBluetoothAdapterStateChange(function callback)
     * 蓝牙适配器状态发生变化事件，这里可用监控蓝牙的关闭和打开动作
     * @param available   boolean 蓝牙适配器是否可用
     * @param discovering boolean 蓝牙适配器是否处于搜索状态
     */
    PAG_NATIVE.onBluetoothAdapterStateChange = function (callback) {
        console.log("PAG_NATIVE.onBluetoothAdapterStateChange");
        if ('function' !== typeof (callback)) {
            return;
        }

        var params = {identifier: _identifer, eventName: SchemeConstants.onBluetoothAdapterStateChange};
        window.pajkRegisterEvent(params.eventName, function (data) {
            console.log("PAG_NATIVE.onBluetoothAdapterStateChange");
            do {
                if ('object' !== typeof (data)) {
                    break;
                }
                callback(data['data']);
            }
            while (0);
        });

        //将事件通知将native
        window.pajkDispatchScheme(null, null, params, SchemeConstants.onBluetoothAdapterStateChange);
    };

    /*
     * PAG_NATIVE.startBluetoothDevicesDiscovery(Object object)
     * 开始搜索设备，蓝牙初始化成功后就可以搜索设备
     * @param services Array<string>
     * @param allowDuplicatesKey boolean
     * @param interval number
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.startBluetoothDevicesDiscovery = function (object) {
        _callCommonFunction(object, SchemeConstants.startBluetoothDevicesDiscovery);
    };

    /*
     * PAG_NATIVE.stopBluetoothDevicesDiscovery(Object object)
     * 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时，建议调用该接口停止蓝牙搜索
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.stopBluetoothDevicesDiscovery = function (object) {
        _callCommonFunction(object, SchemeConstants.stopBluetoothDevicesDiscovery);
    };

    /*
     * PAG_NATIVE.getBluetoothDevices
     * 获取在小程序蓝牙模块生效期间所有已发现的蓝牙设备
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.getBluetoothDevices = function (object) {
        object['identifier'] = _identifer;
        window.pajkDispatchScheme(function (res) {
            if (typeof (object['success']) == 'function') {
                do {
                    if (res['devices'] == undefined) {
                        break;
                    }
                    for (var i = 0; i < res['devices'].length; i++) {
                        if (res['devices'][i]['advertisData'] == undefined || res['devices'][i]['advertisData'].length == 0) {
                            break;
                        }
                        res['devices'][i]['advertisData'] = _hex2ab(res['devices'][i]['advertisData']);
                    }
                    object['success'](res);
                } while (0);
            }
            if (typeof (object['complete']) == 'function') {
                object['complete']('getBluetoothDevices--complete');
            }
        }, function (res) {
            if (typeof (object['fail']) == 'function') {
                object['fail'](res);
            }
            if (typeof (object['complete']) == 'function') {
                object['complete']('getBluetoothDevices--complete');
            }
        }, object, SchemeConstants.getBluetoothDevices);
    };


    /*
     * PAG_NATIVE.onBluetoothDeviceFound(function callback)
     * 当搜索到一个设备时的事件，在此可用过滤目标设备
     */
    PAG_NATIVE.onBluetoothDeviceFound = function (callback) {

        if ('function' !== typeof (callback)) {
            return;
        }

        var params = {identifier: _identifer, eventName: SchemeConstants.onBluetoothDeviceFound};
        window.pajkRegisterEvent(params.eventName, function (data) {
            do {
                if ('object' !== typeof (data)) {
                    break;
                }
                var res = data['data'];
                if ('object' !== typeof (res)) {
                    break;
                }
                var devices = res.devices;
                if ('object' !== typeof (devices)) {
                    break;
                }
                for (var i = 0; i < devices.length; i++) {
                    if (devices[i]['advertisData']) {
                        devices[i]['advertisData'] = _hex2ab(devices[i]['advertisData']);
                    }
                }

                //需要对data数据格式转换data.res.devices
                callback(res);

            } while (0);

        });
        window.pajkDispatchScheme(null, null, params, SchemeConstants.onBluetoothDeviceFound);
    };

    /*
     * PAG_NATIVE.getConnectedBluetoothDevices(Object object)
     * 获取已连接的设备
     * @param services Array<string>
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.getConnectedBluetoothDevices = function (object) {
        console.log('getConnectedBluetoothDevices', '实际的结果');
        _callCommonFunction(object, SchemeConstants.getConnectedBluetoothDevices);
    };

    /*
     * PAG_NATIVE.createBLEConnection(object)
     * 创建BLE连接
     * @param deviceId string
     * @param timeout  number
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.createBLEConnection = function (object) {
        _callCommonFunction(object, SchemeConstants.createBLEConnection);
    };

    /*
     * PAG_NATIVE.closeBLEConnection(object)
     * 关闭BLE连接
     * @param deviceId string (必填)
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.closeBLEConnection = function (object) {
        _callCommonFunction(object, SchemeConstants.closeBLEConnection);
    };

    /*
     * PAG_NATIVE.getBLEDeviceServices(object)
     * 获取设备的服务列表，每个蓝牙设备都有一些服务
     * @param deviceId string (必填)
     * @param success  function
     * @param fail     function
     * @param complete function
     */
    PAG_NATIVE.getBLEDeviceServices = function (object) {
        _callCommonFunction(object, SchemeConstants.getBLEDeviceServices);
    };

    /*
     * PAG_NATIVE.getBLEDeviceCharacteristics(object)
     * 获取蓝牙设备某个服务的特征值列表
     * @param deviceId  string (必填)
     * @param serviceId string (必填)
     * @param success   function
     * @param fail      function
     * @param complete  function
     */
    PAG_NATIVE.getBLEDeviceCharacteristics = function (object) {
        _callCommonFunction(object, SchemeConstants.getBLEDeviceCharacteristics);
    };

    /*
     * PAG_NATIVE.readBLECharacteristicValue(object)
     * 读取低功耗蓝牙设备的特征值的二进制数据值
     * @param deviceId         string (必填)
     * @param serviceId        string (必填)
     * @param characteristicId string (必填)
     * @param success          function
     * @param fail             function
     * @param complete         function
     */
    PAG_NATIVE.readBLECharacteristicValue = function (object) {
        _callCommonFunction(object, SchemeConstants.readBLECharacteristicValue);
    };

    /*
     * PAG_NATIVE.writeBLECharacteristicValue(object)
     * 向蓝牙设备写入数据
     * @param deviceId         string (必填)
     * @param serviceId        string (必填)
     * @param characteristicId string (必填)
     * @param value            ArrayBuffer (必填)
     * @param success          function
     * @param fail             function
     * @param complete         function
     */
    PAG_NATIVE.writeBLECharacteristicValue = function (object) {
        console.log('PAG_NATIVE.writeBLECharacteristicValue');
        var params = {};
        for (var key in object) {
            if (object.hasOwnProperty(key)) {
                var element = object[key];
                if (element instanceof ArrayBuffer) {
                    params[key] = _ab2hex(element);
                } else {
                    params[key] = element;
                }

            }
        }
        _callCommonFunction(params, SchemeConstants.writeBLECharacteristicValue);
    };

    /*
     * PAG_NATIVE.notifyBLECharacteristicValueChange(object)
     * 开启蓝牙设备notify提醒功能，只有开启这个功能才能接受到蓝牙推送的数据
     * @param deviceId         string (必填)
     * @param serviceId        string (必填)
     * @param characteristicId string (必填)
     * @param state            boolean (必填)
     * @param success          function
     * @param fail             function
     * @param complete         function
     */
    PAG_NATIVE.notifyBLECharacteristicValueChange = function (object) {
        console.log('PAG_NATIVE.notifyBLECharacteristicValueChange');
        _callCommonFunction(object, SchemeConstants.notifyBLECharacteristicValueChange);
    };

    /*
     * PAG_NATIVE.onBLEConnectionStateChange(function callback)
     * 监听蓝牙设备错误事件，包括异常断开等等
     */
    PAG_NATIVE.onBLEConnectionStateChange = function (callback) {
        console.log('PAG_NATIVE.onBLEConnectionStateChange');
        if ('function' !== typeof (callback)) {
            return;
        }

        var params = {identifier: _identifer, eventName: SchemeConstants.onBLEConnectionStateChange};

        window.pajkRegisterEvent(params.eventName, callback);
        window.pajkDispatchScheme(null, null, params, SchemeConstants.onBLEConnectionStateChange);
    };

    /*
     * PAG_NATIVE.onBLECharacteristicValueChange(function callback)
     * 监听蓝牙推送的数据，也就是notify数据
     * @param deviceId         string
     * @param serviceId        string
     * @param characteristicId string
     * @param value            ArrayBuffer
     */
    PAG_NATIVE.onBLECharacteristicValueChange = function (callback) {

        if ('function' !== typeof (callback)) {
            return;
        }

        var params = {identifier: _identifer, eventName: SchemeConstants.onBLECharacteristicValueChange};

        window.pajkRegisterEvent(params.eventName, function (data) {
            do {
                if ('object' !== typeof (data)) {
                    break;
                }
                var characteristic = data['data'];
                if ('object' !== typeof (characteristic)) {
                    break;
                }
                if ('string' !== typeof (characteristic.value)) {
                    break;
                }

                if (characteristic.value) {
                    characteristic.value = _hex2ab(characteristic.value);
                }
                callback(characteristic);

            } while (0);
        });
        window.pajkDispatchScheme(null, null, params, SchemeConstants.onBLECharacteristicValueChange);
    };
})();

